Add: - A ::retrieve_surrounding signal that asks the widget for context
authorOwen Taylor <otaylor@redhat.com>
Thu, 1 Nov 2001 21:50:58 +0000 (21:50 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Thu, 1 Nov 2001 21:50:58 +0000 (21:50 +0000)
Thu Nov  1 16:20:56 2001  Owen Taylor  <otaylor@redhat.com>

* gtk/gtkimcontext.[ch]: Add:
  - A ::retrieve_surrounding signal that asks the widget for
    context around the insertion point.
  - A ::delete_surrounding signal that asks the widget to
    delete context aroudn the insertion point.
  - gtk_im_context_set_context() for widgets to set context
    around the insertion point in response to ::retrieve_context.
  - gtk_im_context_get_context() for context to get context
    around the insertion point

* gtkmarshal.list: Add BOOL:INT,INT

* gtk/gtkimmulticontext.c: Proxy the get_surrounding() /
set_surrounding() methods, and the ::retrieve_surrounding /
::delete_surrounding signals.

* gtk/gtkentry.c gtk/gtktreeview.c: Hook up to the
GtkIMContext::retrieve_surrounding / ::delete_surrounding
signals.

14 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkentry.c
gtk/gtkimcontext.c
gtk/gtkimcontext.h
gtk/gtkimmulticontext.c
gtk/gtkmarshal.list
gtk/gtkmarshalers.list
gtk/gtktextview.c

index 3477554c0e13f1e8b1ca64683b485f57b0fa4747..1281ca3a188074deafcb773c02dc75edb735b74f 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,25 @@
+Thu Nov  1 16:20:56 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimcontext.[ch]: Add:
+         - A ::retrieve_surrounding signal that asks the widget for
+           context around the insertion point.
+         - A ::delete_surrounding signal that asks the widget to 
+           delete context aroudn the insertion point.
+         - gtk_im_context_set_context() for widgets to set context
+           around the insertion point in response to ::retrieve_context.
+         - gtk_im_context_get_context() for context to get context
+           around the insertion point
+
+       * gtkmarshal.list: Add BOOL:INT,INT
+
+       * gtk/gtkimmulticontext.c: Proxy the get_surrounding() /
+       set_surrounding() methods, and the ::retrieve_surrounding /
+       ::delete_surrounding signals.
+
+       * gtk/gtkentry.c gtk/gtktreeview.c: Hook up to the
+       GtkIMContext::retrieve_surrounding / ::delete_surrounding
+       signals.
+
 Thu Nov  1 15:45:04 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtktreemodelsort.c (gtk_tree_model_sort_rows_reordered):
index 3477554c0e13f1e8b1ca64683b485f57b0fa4747..1281ca3a188074deafcb773c02dc75edb735b74f 100644 (file)
@@ -1,3 +1,25 @@
+Thu Nov  1 16:20:56 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimcontext.[ch]: Add:
+         - A ::retrieve_surrounding signal that asks the widget for
+           context around the insertion point.
+         - A ::delete_surrounding signal that asks the widget to 
+           delete context aroudn the insertion point.
+         - gtk_im_context_set_context() for widgets to set context
+           around the insertion point in response to ::retrieve_context.
+         - gtk_im_context_get_context() for context to get context
+           around the insertion point
+
+       * gtkmarshal.list: Add BOOL:INT,INT
+
+       * gtk/gtkimmulticontext.c: Proxy the get_surrounding() /
+       set_surrounding() methods, and the ::retrieve_surrounding /
+       ::delete_surrounding signals.
+
+       * gtk/gtkentry.c gtk/gtktreeview.c: Hook up to the
+       GtkIMContext::retrieve_surrounding / ::delete_surrounding
+       signals.
+
 Thu Nov  1 15:45:04 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtktreemodelsort.c (gtk_tree_model_sort_rows_reordered):
index 3477554c0e13f1e8b1ca64683b485f57b0fa4747..1281ca3a188074deafcb773c02dc75edb735b74f 100644 (file)
@@ -1,3 +1,25 @@
+Thu Nov  1 16:20:56 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimcontext.[ch]: Add:
+         - A ::retrieve_surrounding signal that asks the widget for
+           context around the insertion point.
+         - A ::delete_surrounding signal that asks the widget to 
+           delete context aroudn the insertion point.
+         - gtk_im_context_set_context() for widgets to set context
+           around the insertion point in response to ::retrieve_context.
+         - gtk_im_context_get_context() for context to get context
+           around the insertion point
+
+       * gtkmarshal.list: Add BOOL:INT,INT
+
+       * gtk/gtkimmulticontext.c: Proxy the get_surrounding() /
+       set_surrounding() methods, and the ::retrieve_surrounding /
+       ::delete_surrounding signals.
+
+       * gtk/gtkentry.c gtk/gtktreeview.c: Hook up to the
+       GtkIMContext::retrieve_surrounding / ::delete_surrounding
+       signals.
+
 Thu Nov  1 15:45:04 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtktreemodelsort.c (gtk_tree_model_sort_rows_reordered):
index 3477554c0e13f1e8b1ca64683b485f57b0fa4747..1281ca3a188074deafcb773c02dc75edb735b74f 100644 (file)
@@ -1,3 +1,25 @@
+Thu Nov  1 16:20:56 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimcontext.[ch]: Add:
+         - A ::retrieve_surrounding signal that asks the widget for
+           context around the insertion point.
+         - A ::delete_surrounding signal that asks the widget to 
+           delete context aroudn the insertion point.
+         - gtk_im_context_set_context() for widgets to set context
+           around the insertion point in response to ::retrieve_context.
+         - gtk_im_context_get_context() for context to get context
+           around the insertion point
+
+       * gtkmarshal.list: Add BOOL:INT,INT
+
+       * gtk/gtkimmulticontext.c: Proxy the get_surrounding() /
+       set_surrounding() methods, and the ::retrieve_surrounding /
+       ::delete_surrounding signals.
+
+       * gtk/gtkentry.c gtk/gtktreeview.c: Hook up to the
+       GtkIMContext::retrieve_surrounding / ::delete_surrounding
+       signals.
+
 Thu Nov  1 15:45:04 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtktreemodelsort.c (gtk_tree_model_sort_rows_reordered):
index 3477554c0e13f1e8b1ca64683b485f57b0fa4747..1281ca3a188074deafcb773c02dc75edb735b74f 100644 (file)
@@ -1,3 +1,25 @@
+Thu Nov  1 16:20:56 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimcontext.[ch]: Add:
+         - A ::retrieve_surrounding signal that asks the widget for
+           context around the insertion point.
+         - A ::delete_surrounding signal that asks the widget to 
+           delete context aroudn the insertion point.
+         - gtk_im_context_set_context() for widgets to set context
+           around the insertion point in response to ::retrieve_context.
+         - gtk_im_context_get_context() for context to get context
+           around the insertion point
+
+       * gtkmarshal.list: Add BOOL:INT,INT
+
+       * gtk/gtkimmulticontext.c: Proxy the get_surrounding() /
+       set_surrounding() methods, and the ::retrieve_surrounding /
+       ::delete_surrounding signals.
+
+       * gtk/gtkentry.c gtk/gtktreeview.c: Hook up to the
+       GtkIMContext::retrieve_surrounding / ::delete_surrounding
+       signals.
+
 Thu Nov  1 15:45:04 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtktreemodelsort.c (gtk_tree_model_sort_rows_reordered):
index 3477554c0e13f1e8b1ca64683b485f57b0fa4747..1281ca3a188074deafcb773c02dc75edb735b74f 100644 (file)
@@ -1,3 +1,25 @@
+Thu Nov  1 16:20:56 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimcontext.[ch]: Add:
+         - A ::retrieve_surrounding signal that asks the widget for
+           context around the insertion point.
+         - A ::delete_surrounding signal that asks the widget to 
+           delete context aroudn the insertion point.
+         - gtk_im_context_set_context() for widgets to set context
+           around the insertion point in response to ::retrieve_context.
+         - gtk_im_context_get_context() for context to get context
+           around the insertion point
+
+       * gtkmarshal.list: Add BOOL:INT,INT
+
+       * gtk/gtkimmulticontext.c: Proxy the get_surrounding() /
+       set_surrounding() methods, and the ::retrieve_surrounding /
+       ::delete_surrounding signals.
+
+       * gtk/gtkentry.c gtk/gtktreeview.c: Hook up to the
+       GtkIMContext::retrieve_surrounding / ::delete_surrounding
+       signals.
+
 Thu Nov  1 15:45:04 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtktreemodelsort.c (gtk_tree_model_sort_rows_reordered):
index 3477554c0e13f1e8b1ca64683b485f57b0fa4747..1281ca3a188074deafcb773c02dc75edb735b74f 100644 (file)
@@ -1,3 +1,25 @@
+Thu Nov  1 16:20:56 2001  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkimcontext.[ch]: Add:
+         - A ::retrieve_surrounding signal that asks the widget for
+           context around the insertion point.
+         - A ::delete_surrounding signal that asks the widget to 
+           delete context aroudn the insertion point.
+         - gtk_im_context_set_context() for widgets to set context
+           around the insertion point in response to ::retrieve_context.
+         - gtk_im_context_get_context() for context to get context
+           around the insertion point
+
+       * gtkmarshal.list: Add BOOL:INT,INT
+
+       * gtk/gtkimmulticontext.c: Proxy the get_surrounding() /
+       set_surrounding() methods, and the ::retrieve_surrounding /
+       ::delete_surrounding signals.
+
+       * gtk/gtkentry.c gtk/gtktreeview.c: Hook up to the
+       GtkIMContext::retrieve_surrounding / ::delete_surrounding
+       signals.
+
 Thu Nov  1 15:45:04 2001  Jonathan Blandford  <jrb@redhat.com>
 
        * gtk/gtktreemodelsort.c (gtk_tree_model_sort_rows_reordered):
index e3a8804bdc9e3c46962c032e232dcac325f80180..a9c21bebc3b46971596efb81b4c2e10932db3bec 100644 (file)
@@ -232,11 +232,18 @@ static void gtk_entry_keymap_direction_changed (GdkKeymap *keymap,
                                                GtkEntry  *entry);
 /* IM Context Callbacks
  */
-static void gtk_entry_commit_cb           (GtkIMContext      *context,
-                                          const gchar       *str,
-                                          GtkEntry          *entry);
-static void gtk_entry_preedit_changed_cb  (GtkIMContext      *context,
-                                          GtkEntry          *entry);
+static void     gtk_entry_commit_cb               (GtkIMContext *context,
+                                                  const gchar  *str,
+                                                  GtkEntry     *entry);
+static void     gtk_entry_preedit_changed_cb      (GtkIMContext *context,
+                                                  GtkEntry     *entry);
+static gboolean gtk_entry_retrieve_surrounding_cb (GtkIMContext *context,
+                                                  GtkEntry     *entry);
+static gboolean gtk_entry_delete_surrounding_cb   (GtkIMContext *context,
+                                                  gint          offset,
+                                                  gint          n_chars,
+                                                  GtkEntry     *entry);
+
 /* Internal routines
  */
 static void         gtk_entry_set_positions            (GtkEntry       *entry,
@@ -919,6 +926,10 @@ gtk_entry_init (GtkEntry *entry)
                    G_CALLBACK (gtk_entry_commit_cb), entry);
   g_signal_connect (G_OBJECT (entry->im_context), "preedit_changed",
                    G_CALLBACK (gtk_entry_preedit_changed_cb), entry);
+  g_signal_connect (G_OBJECT (entry->im_context), "retrieve_surrounding",
+                   G_CALLBACK (gtk_entry_retrieve_surrounding_cb), entry);
+  g_signal_connect (G_OBJECT (entry->im_context), "delete_surrounding",
+                   G_CALLBACK (gtk_entry_delete_surrounding_cb), entry);
 }
 
 static void
@@ -2272,6 +2283,31 @@ gtk_entry_preedit_changed_cb (GtkIMContext *context,
   gtk_entry_recompute (entry);
 }
 
+static gboolean
+gtk_entry_retrieve_surrounding_cb (GtkIMContext *context,
+                              GtkEntry     *entry)
+{
+  gtk_im_context_set_surrounding (context,
+                                 entry->text,
+                                 entry->n_bytes,
+                                 g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text);
+
+  return TRUE;
+}
+
+static gboolean
+gtk_entry_delete_surrounding_cb (GtkIMContext *slave,
+                                gint          offset,
+                                gint          n_chars,
+                                GtkEntry     *entry)
+{
+  gtk_editable_delete_text (GTK_EDITABLE (entry),
+                           entry->current_pos + offset,
+                           entry->current_pos + offset + n_chars);
+
+  return TRUE;
+}
+
 /* Internal functions
  */
 
index 46057a6ff274f083b278ad00a4e3595ebf94cf96..1e441682afa8cd2611d95a8943e5ab302b9087b1 100644 (file)
  */
 
 #include "gtkimcontext.h"
+#include "gtkmain.h"           /* For _gtk_boolean_handled_accumulator */
 #include "gtksignal.h"
+#include "string.h"
 
 enum {
   PREEDIT_START,
   PREEDIT_END,
   PREEDIT_CHANGED,
   COMMIT,
+  RETRIEVE_SURROUNDING,
+  DELETE_SURROUNDING,
   LAST_SIGNAL
 };
 
@@ -33,12 +37,19 @@ static guint im_context_signals[LAST_SIGNAL] = { 0 };
 static void gtk_im_context_class_init (GtkIMContextClass *class);
 static void gtk_im_context_init (GtkIMContext *im_context);
 
-static void     gtk_im_context_real_get_preedit_string (GtkIMContext       *context,
-                                                       gchar             **str,
-                                                       PangoAttrList     **attrs,
-                                                       gint               *cursor_pos);
-static gboolean gtk_im_context_real_filter_keypress    (GtkIMContext       *context,
-                                                       GdkEventKey        *event);
+static void     gtk_im_context_real_get_preedit_string (GtkIMContext   *context,
+                                                       gchar         **str,
+                                                       PangoAttrList **attrs,
+                                                       gint           *cursor_pos);
+static gboolean gtk_im_context_real_filter_keypress    (GtkIMContext   *context,
+                                                       GdkEventKey    *event);
+static gboolean gtk_im_context_real_get_surrounding    (GtkIMContext   *context,
+                                                       gchar         **text,
+                                                       gint           *cursor_index);
+static void     gtk_im_context_real_set_surrounding    (GtkIMContext   *context,
+                                                       const char     *text,
+                                                       gint            len,
+                                                       gint            cursor_index);
 
 GtkType
 gtk_im_context_get_type (void)
@@ -77,6 +88,8 @@ gtk_im_context_class_init (GtkIMContextClass *klass)
 
   klass->get_preedit_string = gtk_im_context_real_get_preedit_string;
   klass->filter_keypress = gtk_im_context_real_filter_keypress;
+  klass->get_surrounding = gtk_im_context_real_get_surrounding;
+  klass->set_surrounding = gtk_im_context_real_set_surrounding;
 
   im_context_signals[PREEDIT_START] =
     gtk_signal_new ("preedit_start",
@@ -110,6 +123,25 @@ gtk_im_context_class_init (GtkIMContextClass *klass)
                    gtk_marshal_VOID__STRING,
                    GTK_TYPE_NONE, 1,
                    GTK_TYPE_STRING);
+
+  im_context_signals[RETRIEVE_SURROUNDING] =
+    g_signal_new ("retrieve_surrounding",
+                  GTK_CLASS_TYPE (object_class),
+                  GTK_RUN_LAST,
+                  GTK_SIGNAL_OFFSET (GtkIMContextClass, retrieve_surrounding),
+                  _gtk_boolean_handled_accumulator, NULL,
+                  gtk_marshal_BOOLEAN__VOID,
+                  GTK_TYPE_BOOL, 0);
+  im_context_signals[DELETE_SURROUNDING] =
+    g_signal_new ("delete_surrounding",
+                  GTK_CLASS_TYPE (object_class),
+                  GTK_RUN_LAST,
+                  GTK_SIGNAL_OFFSET (GtkIMContextClass, delete_surrounding),
+                  _gtk_boolean_handled_accumulator, NULL,
+                  gtk_marshal_BOOLEAN__INT_INT,
+                  GTK_TYPE_BOOL, 2,
+                  GTK_TYPE_INT,
+                 GTK_TYPE_INT);
 }
 
 static void
@@ -138,6 +170,67 @@ gtk_im_context_real_filter_keypress (GtkIMContext       *context,
   return FALSE;
 }
 
+typedef struct
+{
+  gchar *text;
+  gint cursor_index;
+} SurroundingInfo;
+
+static void
+gtk_im_context_real_set_surrounding (GtkIMContext  *context,
+                                    const gchar   *text,
+                                    gint           len,
+                                    gint           cursor_index)
+{
+  SurroundingInfo *info = g_object_get_data (G_OBJECT (context), "gtk-im-surrounding-info");
+
+  if (info)
+    {
+      g_free (info->text);
+      info->text = g_strndup (text, len);
+      info->cursor_index = cursor_index;
+    }
+}
+
+static gboolean
+gtk_im_context_real_get_surrounding (GtkIMContext *context,
+                                    gchar       **text,
+                                    gint         *cursor_index)
+{
+  gboolean result;
+  gboolean info_is_local = FALSE;
+  SurroundingInfo local_info = { NULL, 0 };
+  SurroundingInfo *info;
+  
+  info = g_object_get_data (G_OBJECT (context), "gtk-im-surrounding-info");
+  if (!info)
+    {
+      info = &local_info;
+      g_object_set_data (G_OBJECT (context), "gtk-im-surrounding-info", info);
+      info_is_local = TRUE;
+    }
+  
+  g_signal_emit (context,
+                im_context_signals[RETRIEVE_SURROUNDING], 0,
+                &result);
+
+  if (result)
+    {
+      *text = g_strdup (info->text ? info->text : "");
+      *cursor_index = info->cursor_index;
+    }
+  else
+    {
+      *text = NULL;
+      *cursor_index = 0;
+    }
+
+  if (info_is_local)
+    g_free (info->text);
+  
+  return result;
+}
+
 /**
  * gtk_im_context_set_client_window:
  * @context: a #GtkIMContext
@@ -324,3 +417,133 @@ gtk_im_context_set_use_preedit (GtkIMContext *context,
   if (klass->set_use_preedit)
     klass->set_use_preedit (context, use_preedit);
 }
+
+/**
+ * gtk_im_context_set_surrounding:
+ * @context: a #GtkIMContext 
+ * @text: text surrounding the insertion point, as UTF-8.
+ *        the preedit string should not be included within
+ *        @text.
+ * @len: the length of @text, or -1 if @text is nul-terminated
+ * @cursor_index: the byte index of the insertion cursor within @text.
+ * 
+ * Sets surrounding context around the insertion point and preedit
+ * string. This function is expected to be called in response to the
+ * GtkIMContext::retrieve_context signal, and will likely have no
+ * effect if called at other times.
+ **/
+void
+gtk_im_context_set_surrounding (GtkIMContext  *context,
+                               const gchar   *text,
+                               gint           len,
+                               gint           cursor_index)
+{
+  GtkIMContextClass *klass;
+  
+  g_return_if_fail (GTK_IS_IM_CONTEXT (context));
+  g_return_if_fail (text != NULL || len == 0);
+
+  if (text == NULL && len == 0)
+    text = "";
+  if (len < 0)
+    len = strlen (text);
+
+  g_return_if_fail (cursor_index >= 0 && cursor_index <= len);
+
+  klass = GTK_IM_CONTEXT_GET_CLASS (context);
+  if (klass->set_surrounding)
+    klass->set_surrounding (context, text, len, cursor_index);
+}
+
+/**
+ * gtk_im_context_get_surrounding:
+ * @context: a #GtkIMContext
+ * @text: location to store a UTF-8 encoded string of text
+ *        holding context around the insertion point.
+ *        If the function returns %TRUE, then you must free
+ *        the result stored in this location with g_free().
+ * @cursor_index: location to store byte index of the insertion cursor
+ *        within @text.
+ * 
+ * Retrieves context around the insertion point. Input methods
+ * typically want context in order to constrain input text based on
+ * existing text; this is important for languages such as Thai where
+ * only some sequences of characters are allowed.
+ *
+ * This function is implemented by emitting the
+ * GtkIMContext::retrieve_context signal on the input method; in
+ * response to this signal, a widget should provide as much context as
+ * is available, up to an entire paragraph, by calling
+ * gtk_im_context_set_surrounding. Note that there is no obligation
+ * for a widget to respond to the ::retrieve_context signal, so input
+ * methods must be prepared to function without context.
+ *
+ * Return value: %TRUE if surrounding text was provided; in this case
+ *    you must free the result stored in *text.
+ **/
+gboolean
+gtk_im_context_get_surrounding (GtkIMContext *context,
+                               gchar       **text,
+                               gint         *cursor_index)
+{
+  GtkIMContextClass *klass;
+  gchar *local_text = NULL;
+  gint local_index;
+  gboolean result = FALSE;
+  
+  g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE);
+
+  klass = GTK_IM_CONTEXT_GET_CLASS (context);
+  if (klass->get_surrounding)
+    result = klass->get_surrounding (context,
+                                    text ? text : &local_text,
+                                    cursor_index ? cursor_index : &local_index);
+
+  if (result)
+    g_free (local_text);
+
+  return result;
+}
+
+/**
+ * gtk_im_context_delete_surrounding:
+ * @context: a #GtkIMContext
+ * @offset: offset from cursor position in chars;
+ *    a negative value means start before the cursor.
+ * @n_chars: number of characters to delete.
+ * 
+ * Asks the widget that the input context is attached to to delete
+ * characters around the cursor position by emitting the
+ * GtkIMContext::delete_context signal. Note that @offset and @n_chars
+ * are in characters not in bytes, which differs from the usage other
+ * places in #GtkIMContext.
+ *
+ * In order to use this function, you should first call
+ * gtk_im_context_get_surrounding() to get the current context, and
+ * call this function immediately afterwards to make sure that you
+ * know what you are deleting. You should also account for the fact
+ * that even if the signal was handled, the input context might not
+ * have deleted all the characters that were requested to be deleted.
+ *
+ * This function is used by an input method that wants to make
+ * subsitutions in the existing text in response to new input. It is
+ * not useful for applications.
+ * 
+ * Return value: %TRUE if the signal was handled.
+ **/
+gboolean
+gtk_im_context_delete_surrounding (GtkIMContext *context,
+                                  gint          offset,
+                                  gint          n_chars)
+{
+  gboolean result;
+  
+  g_return_val_if_fail (GTK_IS_IM_CONTEXT (context), FALSE);
+
+  g_signal_emit (context,
+                im_context_signals[DELETE_SURROUNDING], 0,
+                offset, n_chars, &result);
+
+  return result;
+}
+
index 0b5d8f37596781aadd1f6a463adcc44d7162c2fa..1f1433873e875b74790b7a49a4a01a6c83939085 100644 (file)
@@ -50,10 +50,14 @@ struct _GtkIMContextClass
   GtkObjectClass parent_class;
 
   /* Signals */
-  void (*preedit_start)   (GtkIMContext *context);
-  void (*preedit_end)     (GtkIMContext *context);
-  void (*preedit_changed) (GtkIMContext *context);
-  void (*commit)          (GtkIMContext *context, const gchar *str);
+  void     (*preedit_start)        (GtkIMContext *context);
+  void     (*preedit_end)          (GtkIMContext *context);
+  void     (*preedit_changed)      (GtkIMContext *context);
+  void     (*commit)               (GtkIMContext *context, const gchar *str);
+  gboolean (*retrieve_surrounding) (GtkIMContext *context);
+  gboolean (*delete_surrounding)   (GtkIMContext *context,
+                                   gint          offset,
+                                   gint          n_chars);
 
   /* Virtual functions */
   void     (*set_client_window)   (GtkIMContext   *context,
@@ -71,25 +75,43 @@ struct _GtkIMContextClass
                                   GdkRectangle   *area);
   void     (*set_use_preedit)     (GtkIMContext   *context,
                                   gboolean        use_preedit);
+  void     (*set_surrounding)     (GtkIMContext   *context,
+                                  const gchar    *text,
+                                  gint            len,
+                                  gint            cursor_index);
+  gboolean (*get_surrounding)     (GtkIMContext   *context,
+                                  gchar         **text,
+                                  gint           *cursor_index);
 };
 
 GtkType       gtk_im_context_get_type           (void) G_GNUC_CONST;
 
-void          gtk_im_context_set_client_window  (GtkIMContext   *context,
-                                                GdkWindow      *window);
-void          gtk_im_context_get_preedit_string (GtkIMContext   *context,
-                                                gchar         **str,
-                                                PangoAttrList **attrs,
-                                                gint           *cursor_pos);
-gboolean      gtk_im_context_filter_keypress    (GtkIMContext   *context,
-                                                GdkEventKey    *event);
-void          gtk_im_context_focus_in           (GtkIMContext   *context);
-void          gtk_im_context_focus_out          (GtkIMContext   *context);
-void          gtk_im_context_reset              (GtkIMContext   *context);
-void          gtk_im_context_set_cursor_location (GtkIMContext   *context,
-                                                 GdkRectangle  *area);
-void          gtk_im_context_set_use_preedit     (GtkIMContext   *context,
-                                                 gboolean        use_preedit);
+void     gtk_im_context_set_client_window   (GtkIMContext   *context,
+                                            GdkWindow      *window);
+void     gtk_im_context_get_preedit_string  (GtkIMContext   *context,
+                                            gchar         **str,
+                                            PangoAttrList **attrs,
+                                            gint           *cursor_pos);
+gboolean gtk_im_context_filter_keypress     (GtkIMContext   *context,
+                                            GdkEventKey    *event);
+void     gtk_im_context_focus_in            (GtkIMContext   *context);
+void     gtk_im_context_focus_out           (GtkIMContext   *context);
+void     gtk_im_context_reset               (GtkIMContext   *context);
+void     gtk_im_context_set_cursor_location (GtkIMContext   *context,
+                                            GdkRectangle   *area);
+void     gtk_im_context_set_use_preedit     (GtkIMContext   *context,
+                                            gboolean        use_preedit);
+void     gtk_im_context_set_surrounding     (GtkIMContext   *context,
+                                            const gchar    *text,
+                                            gint            len,
+                                            gint            cursor_index);
+gboolean gtk_im_context_get_surrounding     (GtkIMContext   *context,
+                                            gchar         **text,
+                                            gint           *cursor_index);
+gboolean gtk_im_context_delete_surrounding  (GtkIMContext   *context,
+                                            gint            offset,
+                                            gint            n_chars);
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index e8a81af9754a879bb9de197f58fb87fab5b9a31c..4d4cce66ba7ecdc493ed4992d4734a597240f029 100644 (file)
@@ -45,17 +45,29 @@ static void     gtk_im_multicontext_focus_out          (GtkIMContext
 static void     gtk_im_multicontext_reset              (GtkIMContext            *context);
 static void     gtk_im_multicontext_set_cursor_location (GtkIMContext            *context,
                                                        GdkRectangle            *area);
-
-static void     gtk_im_multicontext_preedit_start_cb   (GtkIMContext            *slave,
-                                                       GtkIMMulticontext       *multicontext);
-static void     gtk_im_multicontext_preedit_end_cb     (GtkIMContext            *slave,
-                                                       GtkIMMulticontext       *multicontext);
-static void     gtk_im_multicontext_preedit_changed_cb (GtkIMContext            *slave,
-                                                       GtkIMMulticontext       *multicontext);
-void            gtk_im_multicontext_commit_cb          (GtkIMContext            *slave,
-                                                       const gchar             *str,
-                                                       GtkIMMulticontext       *multicontext);
-
+static gboolean gtk_im_multicontext_get_surrounding    (GtkIMContext            *context,
+                                                       gchar                  **text,
+                                                       gint                    *cursor_index);
+static void     gtk_im_multicontext_set_surrounding    (GtkIMContext            *context,
+                                                       const char              *text,
+                                                       gint                     len,
+                                                       gint                     cursor_index);
+
+static void     gtk_im_multicontext_preedit_start_cb        (GtkIMContext      *slave,
+                                                            GtkIMMulticontext *multicontext);
+static void     gtk_im_multicontext_preedit_end_cb          (GtkIMContext      *slave,
+                                                            GtkIMMulticontext *multicontext);
+static void     gtk_im_multicontext_preedit_changed_cb      (GtkIMContext      *slave,
+                                                            GtkIMMulticontext *multicontext);
+static void     gtk_im_multicontext_commit_cb               (GtkIMContext      *slave,
+                                                            const gchar       *str,
+                                                            GtkIMMulticontext *multicontext);
+static gboolean gtk_im_multicontext_retrieve_surrounding_cb (GtkIMContext      *slave,
+                                                            GtkIMMulticontext *multicontext);
+static gboolean gtk_im_multicontext_delete_surrounding_cb   (GtkIMContext      *slave,
+                                                            gint               offset,
+                                                            gint               n_chars,
+                                                            GtkIMMulticontext *multicontext);
 static GtkIMContextClass *parent_class;
 
 static const gchar *global_context_id = NULL;
@@ -103,6 +115,8 @@ gtk_im_multicontext_class_init (GtkIMMulticontextClass *class)
   im_context_class->focus_out = gtk_im_multicontext_focus_out;
   im_context_class->reset = gtk_im_multicontext_reset;
   im_context_class->set_cursor_location = gtk_im_multicontext_set_cursor_location;
+  im_context_class->set_surrounding = gtk_im_multicontext_set_surrounding;
+  im_context_class->get_surrounding = gtk_im_multicontext_get_surrounding;
 
   gobject_class->finalize = gtk_im_multicontext_finalize;
 }
@@ -174,6 +188,12 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
       g_signal_connect (multicontext->slave, "commit",
                        G_CALLBACK (gtk_im_multicontext_commit_cb),
                        multicontext);
+      g_signal_connect (multicontext->slave, "retrieve_surrounding",
+                       G_CALLBACK (gtk_im_multicontext_retrieve_surrounding_cb),
+                       multicontext);
+      g_signal_connect (multicontext->slave, "delete_surrounding",
+                       G_CALLBACK (gtk_im_multicontext_delete_surrounding_cb),
+                       multicontext);
       
       if (multicontext->client_window)
        gtk_im_context_set_client_window (slave, multicontext->client_window);
@@ -301,6 +321,40 @@ gtk_im_multicontext_set_cursor_location (GtkIMContext   *context,
     gtk_im_context_set_cursor_location (slave, area);
 }
 
+static gboolean
+gtk_im_multicontext_get_surrounding (GtkIMContext  *context,
+                                    gchar        **text,
+                                    gint          *cursor_index)
+{
+  GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
+  GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
+
+  if (slave)
+    return gtk_im_context_get_surrounding (context, text, cursor_index);
+  else
+    {
+      if (text)
+       *text = NULL;
+      if (cursor_index)
+       *cursor_index = 0;
+
+      return FALSE;
+    }
+}
+
+static void
+gtk_im_multicontext_set_surrounding (GtkIMContext *context,
+                                    const char   *text,
+                                    gint          len,
+                                    gint          cursor_index)
+{
+  GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
+  GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
+
+  if (slave)
+    gtk_im_context_set_surrounding (slave, text, len, cursor_index);
+}
+
 static void
 gtk_im_multicontext_preedit_start_cb   (GtkIMContext      *slave,
                                        GtkIMMulticontext *multicontext)
@@ -322,7 +376,7 @@ gtk_im_multicontext_preedit_changed_cb (GtkIMContext      *slave,
   g_signal_emit_by_name (multicontext, "preedit_changed");
 }
 
-void
+static void
 gtk_im_multicontext_commit_cb (GtkIMContext      *slave,
                               const gchar       *str,
                               GtkIMMulticontext *multicontext)
@@ -330,6 +384,31 @@ gtk_im_multicontext_commit_cb (GtkIMContext      *slave,
   g_signal_emit_by_name (multicontext, "commit", str);;
 }
 
+static gboolean
+gtk_im_multicontext_retrieve_surrounding_cb (GtkIMContext      *slave,
+                                            GtkIMMulticontext *multicontext)
+{
+  gboolean result;
+  
+  g_signal_emit_by_name (multicontext, "retrieve_surrounding", &result);
+
+  return result;
+}
+
+static gboolean
+gtk_im_multicontext_delete_surrounding_cb (GtkIMContext      *slave,
+                                          gint               offset,
+                                          gint               n_chars,
+                                          GtkIMMulticontext *multicontext)
+{
+  gboolean result;
+  
+  g_signal_emit_by_name (multicontext, "delete_surrounding",
+                        offset, n_chars, &result);
+
+  return result;
+}
+
 static void
 activate_cb (GtkWidget         *menuitem,
             GtkIMMulticontext *context)
index 23a66260e6cad4aa0b40d6ed95bfb47c96f9a892..84b23e024c0aaaf305aeb0ece97bed966f0e28c9 100644 (file)
@@ -27,6 +27,7 @@ BOOLEAN:ENUM
 BOOLEAN:OBJECT,INT,INT,UINT
 BOOLEAN:OBJECT,STRING,STRING,BOXED
 BOOLEAN:OBJECT,BOXED,BOXED
+BOOLEAN:INT,INT
 BOOLEAN:VOID
 BOOLEAN:BOOLEAN
 ENUM:ENUM
index 23a66260e6cad4aa0b40d6ed95bfb47c96f9a892..84b23e024c0aaaf305aeb0ece97bed966f0e28c9 100644 (file)
@@ -27,6 +27,7 @@ BOOLEAN:ENUM
 BOOLEAN:OBJECT,INT,INT,UINT
 BOOLEAN:OBJECT,STRING,STRING,BOXED
 BOOLEAN:OBJECT,BOXED,BOXED
+BOOLEAN:INT,INT
 BOOLEAN:VOID
 BOOLEAN:BOOLEAN
 ENUM:ENUM
index d45b1891ab3f9345aa61cf593da842babeee64ba..538dbb4f2b401ae5315ba9c5698a514a29721036 100644 (file)
@@ -257,13 +257,19 @@ static void     gtk_text_view_check_cursor_blink     (GtkTextView        *text_v
 static void     gtk_text_view_pend_cursor_blink      (GtkTextView        *text_view);
 static void     gtk_text_view_stop_cursor_blink      (GtkTextView        *text_view);
 
-static void gtk_text_view_value_changed           (GtkAdjustment *adj,
-                                                  GtkTextView   *view);
-static void gtk_text_view_commit_handler          (GtkIMContext  *context,
-                                                  const gchar   *str,
-                                                  GtkTextView   *text_view);
-static void gtk_text_view_preedit_changed_handler (GtkIMContext  *context,
-                                                  GtkTextView   *text_view);
+static void     gtk_text_view_value_changed                (GtkAdjustment *adj,
+                                                           GtkTextView   *view);
+static void     gtk_text_view_commit_handler               (GtkIMContext  *context,
+                                                           const gchar   *str,
+                                                           GtkTextView   *text_view);
+static void     gtk_text_view_preedit_changed_handler      (GtkIMContext  *context,
+                                                           GtkTextView   *text_view);
+static gboolean gtk_text_view_retrieve_surrounding_handler (GtkIMContext  *context,
+                                                           GtkTextView   *text_view);
+static gboolean gtk_text_view_delete_surrounding_handler   (GtkIMContext  *context,
+                                                           gint           offset,
+                                                           gint           n_chars,
+                                                           GtkTextView   *text_view);
 
 static void gtk_text_view_mark_set_handler       (GtkTextBuffer     *buffer,
                                                   const GtkTextIter *location,
@@ -956,9 +962,12 @@ gtk_text_view_init (GtkTextView *text_view)
 
   g_signal_connect (G_OBJECT (text_view->im_context), "commit",
                     G_CALLBACK (gtk_text_view_commit_handler), text_view);
-
   g_signal_connect (G_OBJECT (text_view->im_context), "preedit_changed",
                    G_CALLBACK (gtk_text_view_preedit_changed_handler), text_view);
+  g_signal_connect (G_OBJECT (text_view->im_context), "retrieve_surrounding",
+                   G_CALLBACK (gtk_text_view_retrieve_surrounding_handler), text_view);
+  g_signal_connect (G_OBJECT (text_view->im_context), "delete_surrounding",
+                   G_CALLBACK (gtk_text_view_delete_surrounding_handler), text_view);
 
   text_view->cursor_visible = TRUE;
 
@@ -5309,6 +5318,51 @@ gtk_text_view_preedit_changed_handler (GtkIMContext *context,
   g_free (str);
 }
 
+static gboolean
+gtk_text_view_retrieve_surrounding_handler (GtkIMContext  *context,
+                                           GtkTextView   *text_view)
+{
+  GtkTextIter start;
+  GtkTextIter end;
+  gint pos;
+  gchar *text;
+
+  gtk_text_buffer_get_iter_at_mark (text_view->buffer, &start,  
+                                   gtk_text_buffer_get_insert (text_view->buffer));
+  end = start;
+
+  pos = gtk_text_iter_get_line_index (&start);
+  gtk_text_iter_set_line_offset (&start, 0);
+  gtk_text_iter_forward_to_line_end (&end);
+
+  text = gtk_text_iter_get_slice (&start, &end);
+  gtk_im_context_set_surrounding (context, text, -1, pos);
+  g_free (text);
+
+  return TRUE;
+}
+
+static gboolean
+gtk_text_view_delete_surrounding_handler (GtkIMContext  *context,
+                                         gint           offset,
+                                         gint           n_chars,
+                                         GtkTextView   *text_view)
+{
+  GtkTextIter start;
+  GtkTextIter end;
+
+  gtk_text_buffer_get_iter_at_mark (text_view->buffer, &start,  
+                                   gtk_text_buffer_get_insert (text_view->buffer));
+  end = start;
+
+  gtk_text_iter_forward_chars (&start, offset);
+  gtk_text_iter_forward_chars (&end, offset + n_chars);
+
+  gtk_text_buffer_delete (text_view->buffer, &start, &end);
+
+  return TRUE;
+}
+
 static void
 gtk_text_view_mark_set_handler (GtkTextBuffer     *buffer,
                                 const GtkTextIter *location,